package com.sinocst.sap3;

import java.io.BufferedReader;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;

import org.json.JSONException;
import org.json.JSONObject;

/**
 * @Project: JavaWebSAPAPI
 * @Author: zhang10092009@hotmail.com
 * @Date: 2018/2/26  15:34
 * @Description:
 *
 * 大部分消息格式可以从《SAP BusinessObjects Web Intelligence RESTful Web Service SDK Developer Guide》获取，
 * 但某些消息格式无法从《SAP BusinessObjects Web Intelligence RESTful Web Service SDK Developer Guide》获取，
 * 需要从Restful接口获取。通常在做法是。
 * a.) 用BO的客户端工具做一个范例
 * b.) 再用Restful的接口获取相应的消息格式
 *  例如 “报表的Specification”
 *  URL http://10.173.1.153:6405/biprws/raylight/v1/documents/6403/reports/1/specification
 */
public class ExportWebiReportFor41 {
    /**
     * CMS System
     */
    private static final String CMS_LOG_HOST = "192.168.72.145:6405";
    /**
     * User name used to log in to the CMS
     */
    private static final String CMS_LOG_USER = "Administrator";
    /**
     * User password
     */
    private static final String CMS_LOG_PASS = "SAPoem123";
    /**
     * Authentication mode used to log in to the CMS. Here: Enterprise
     */
    private static final String CMS_AUTH_MODE = "secEnterprise";
    private static final String WEBI_URL = "/biprws/raylight/v1";
    private String logonToken;
    private boolean isLogon = false;
    private String documentID = "25954";
    // private String documentID = "5762";
    private String reportID = "1";
    // private String dataProviderID = "106091";
    private String dataProviderID = "DP0";

    public static void main(String[] args) throws JSONException, ParseException, IOException {
        ExportWebiReportFor41 webiRep = new ExportWebiReportFor41();
        JSONObject json = null;
        String resultStr = null;
        webiRep.getLogonToken();
        resultStr = webiRep.getReportHtml();
        System.out.println(resultStr);
        if (json != null) {
            System.out.println(json.toString());
        }
    }

    public String getReportHtml() throws IOException, ParseException, JSONException {
        String urlStr = "http://" + CMS_LOG_HOST + WEBI_URL + "/documents/" + this.documentID + "/reports/" + this.reportID;
        return this.getContentHTML(urlStr);
    }

    public JSONObject refreshDataProvider() throws IOException, ParseException, JSONException {
        String urlStr = "http://" + CMS_LOG_HOST + WEBI_URL + "/documents/" + this.documentID
                + "/dataproviders/" + this.dataProviderID + "/parameters?refresh=true";
        JSONObject json = this.getContentJson(urlStr);
        return json;
    }

    public JSONObject refreshDocument() throws IOException, ParseException, JSONException {
        String urlStr = "http://" + CMS_LOG_HOST + WEBI_URL + "/documents/"
//         + this.documentID + "/parameters?refresh=true";
                + this.documentID + "/parameters";
//         JSONObject json = this.putXmlContentJson(urlStr, "");
        JSONObject json = this.getContentJson(urlStr);
        return json;
    }

    public String getLogonToken() throws ParseException, IOException, JSONException {
        String body = "<attrs xmlns=\"http://www.sap.com/rws/bip\">"
                + "<attr name=\"userName\" type=\"string\">" + CMS_LOG_USER + "</attr>"
                + "<attr name=\"password\" type=\"string\">" + CMS_LOG_PASS + "</attr>"
                + "<attr name=\"auth\" type=\"string\" possibilities=\"secEnterprise,secLDAP,secWinAD\">" + CMS_AUTH_MODE + "</attr>"
                + "</attrs>";
        JSONObject json = postContentJson("http://" + CMS_LOG_HOST + "/biprws/logon/long/", body);
        logonToken = (String) json.get("logonToken");
        isLogon = true;
        return logonToken;
    }

    private String getContentHTML(String urlStr) throws IOException, JSONException {
        return this.getContentStr(urlStr, "text/html");
    }

    private String getContentStr(String urlStr, String acceptType) throws IOException, JSONException {
        return getAndDeleteContentStr(urlStr, acceptType, "GET");
    }

    private String getAndDeleteContentStr(String urlStr, String acceptType, String method) throws IOException, JSONException {
        System.out.println(urlStr);
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod(method);
        if (this.isLogon) {
            conn.setRequestProperty("X-SAP-LogonToken", "\"" + logonToken + "\"");
        }
        conn.setRequestProperty("Accept", acceptType);
        conn.setRequestProperty("Content-Type", "application/xml; charset=utf-8");
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.connect();
        if (conn.getResponseCode() != 200) {
            throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
        }
        byte[] buffer = new byte[1024];
        String sFinal = "";
        int bytesRead = 0;
        BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
        while ((bytesRead = bis.read(buffer)) != -1) {
            sFinal = sFinal + new String(buffer, 0, bytesRead);
        }
        bis.close();
        conn.disconnect();
        return sFinal;
    }

    private JSONObject getContentJson(String urlStr) throws IOException, JSONException {
        System.out.println(urlStr);
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        if (this.isLogon) {
            conn.setRequestProperty("X-SAP-LogonToken", "\"" + logonToken + "\"");
        }
        conn.setRequestProperty("Accept", "application/json");
        conn.setRequestProperty("Content-Type", "application/xml; charset=utf-8");
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.connect();
        if (conn.getResponseCode() != 200) {
            throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
        }
        BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
        String jsontxt = br.readLine();
        br.close();
        JSONObject json = new JSONObject(jsontxt);
        conn.disconnect();
        return json;
    }

    private JSONObject postContentJson(String urlStr, String body) throws IOException, JSONException {
        return postAndPutContentJson(urlStr, body, "POST", "application/xml; charset=utf-8");
    }

    private JSONObject postAndPutContentJson(String urlStr, String body, String method, String contentType) throws IOException, JSONException {
        System.out.println(urlStr);
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod(method);
        if (this.isLogon) {
            conn.setRequestProperty("X-SAP-LogonToken", "\"" + logonToken + "\"");
        }
        conn.setRequestProperty("Accept", "application/json");
        conn.setRequestProperty("Content-Type", contentType);
        conn.setDoInput(true);
        conn.setDoOutput(true);
        int len = body.length();
        conn.setRequestProperty("Content-Length", Integer.toString(len));
        conn.connect();
        OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
        out.write(body, 0, len);
        out.flush();
        if (conn.getResponseCode() != 200) {
            throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
        }
        BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
        String jsontxt = br.readLine();
        br.close();
        conn.disconnect();
        JSONObject json = new JSONObject(jsontxt);
        return json;
    }
}
